home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume11 / larn / part01 next >
Encoding:
Internet Message Format  |  1991-01-03  |  54.2 KB

  1. Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v11i084:  larn - dungeon type adventure game, Part01/11
  5. Message-ID: <6715@tekred.CNA.TEK.COM>
  6. Date: 18 Dec 90 18:28:30 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 1751
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
  12. Posting-number: Volume 11, Issue 84
  13. Archive-name: larn/Part01
  14. Environment: Unix, VMS, MS-DOS, termcap
  15.  
  16.     [This is the source for Larn V12.2, an enhancement of the
  17.      original Larn (written by Noah Morgan) by Kevin Routley.
  18.      This version is different than Ularn which was previously
  19.      posted in volume 7 and is closer to the original in
  20.      "look and feel". It is known to compile on Unix, VMS and
  21.      MS-DOS. PC executables were previously posted to
  22.      comp.binaries.ibm.pc.  -br]
  23.  
  24. #! /bin/sh
  25. # This is a shell archive.  Remove anything before this line, then unpack
  26. # it by saving it into a file and typing "sh file".  To overwrite existing
  27. # files, type "sh file -c".  You can also feed this as standard input via
  28. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  29. # will see the following message at the end:
  30. #        "End of archive 1 (of 11)."
  31. # Contents:  README MANIFEST descrip.mms main.c
  32. # Wrapped by billr@saab on Tue Dec 18 10:14:12 1990
  33. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  34. if test -f 'README' -a "${1}" != "-c" ; then 
  35.   echo shar: Will not clobber existing file \"'README'\"
  36. else
  37. echo shar: Extracting \"'README'\" \(1362 characters\)
  38. sed "s/^X//" >'README' <<'END_OF_FILE'
  39. XAs promised, here is the source to Larn V12.2, the executables for which were
  40. Xposted earlier this year to comp.binaries.ibm.pc.
  41. X
  42. XThe source correctly compiles and executes under DEC Ultrix, using the cc
  43. Xcompiler.  The enclosed Makefile is for U*ix systems.
  44. X
  45. XThe source correctly compiles and executes under VAX/VMS, using the VAX C V3.x
  46. Xcompiler.  The enclosed descrip.mms is a MMS file for building under VAX/VMS.
  47. X
  48. XThe source correctly compiles and executes under MS-DOS, using Turbo C V2.0 or
  49. XTurbo C++ V1.0.  The LARN.PRJ file is for Turbo C V2.0, but unfortunately I am
  50. Xunable to properly distribute the Turbo C++ project file and setup files.  To
  51. Xcompiler under MS-DOS, you must define the MSDOS, DGK, SYSV, DGK_MSDOS and
  52. XNOVARARGS defines.
  53. X
  54. XI am interested in receiving source changes that allow Larn to be ported to
  55. Xother architectures or operating systems.  I am also interested in constructive
  56. Xchanges or additions to improve the game.  I am _not_ interested in arbitrary
  57. Xmods, a la UltraLarn.
  58. X
  59. XBug fixes, bug reports, and requests welcome.
  60. X
  61. XI am reachable at tle.enet.dec.com!routley or routley@tle.enet.dec.com.
  62. XBecause I am right in the middle of moving at the moment, all USmail should be
  63. Xsent to:
  64. X
  65. XKevin Routley
  66. XDigital Equipment Corporation
  67. XZKO2-3/N30
  68. X110 Spitbrook Road
  69. XNashua, NH  03060
  70. X
  71. Xinstead of the address listed in the documentation file.
  72. END_OF_FILE
  73. if test 1362 -ne `wc -c <'README'`; then
  74.     echo shar: \"'README'\" unpacked with wrong size!
  75. fi
  76. # end of 'README'
  77. fi
  78. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  79.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  80. else
  81. echo shar: Extracting \"'MANIFEST'\" \(2286 characters\)
  82. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  83. X   File Name        Archive #    Description
  84. X-----------------------------------------------------------
  85. X MANIFEST                   1    This shipping list
  86. X Makefile                   5    Makefile for U*ix.
  87. X README                     1    
  88. X action.c                   9    
  89. X bill.c                     7    
  90. X config.c                  11    
  91. X create.c                   8    
  92. X data.c                     2    
  93. X descrip.mms                1    MMS build file for VAX/VMS
  94. X diag.c                     8    
  95. X display.c                  2    
  96. X fgetlr.c                  11    Termcap support for VMS/MS-DOS.
  97. X fortune.c                 11    
  98. X global.c                   7    
  99. X header.h                   8    
  100. X help.c                    11    
  101. X io.c                       7    
  102. X larn.ftn                  11    Fortune File
  103. X larn.maz                   6    Maze file
  104. X larn.opt                   2    Simple options file.  Rename to .larnopts for U*ix.
  105. X larn.prj                   2    Turbo C V2.0 Project File
  106. X larn122.doc                6    Documentation for Larn V12.2
  107. X larn122.fix               11    List of changes since Larn V12.0
  108. X larn_hlp.uue               9    Uuencoded help file with ansi escape sequences
  109. X larnhlp.txt               10    Help file without ansi escape sequences
  110. X main.c                     1    
  111. X monster.c                  4    
  112. X moreobj.c                  9    
  113. X movem.c                    5    
  114. X msdos.c                   10    MS-DOS Specific code.
  115. X nansi.doc                  8    Documentation for NANSI.SYS, a MS-DOS ANSI.SYS replacement
  116. X nansisys.uue              11    UUENCODED NANSI.SYS
  117. X nap.c                     11    
  118. X object.c                   4    
  119. X regen.c                    9    
  120. X savelev.c                  5    
  121. X scores.c                   3    
  122. X signal.c                  11    
  123. X spells.c                   5    
  124. X spheres.c                 10    
  125. X store.c                    3    
  126. X termcap.pc                 4    Termcap file for MS-DOS.
  127. X termcap.vms               11    Termcap file for VMS.
  128. X tgetent.c                  9    Termcap support for VMS/MS-DOS.
  129. X tgetstr.c                  6    Termcap support for VMS/MS-DOS.
  130. X tgoto.c                   10    Termcap support for VMS/MS-DOS.
  131. X tok.c                     10    
  132. X tputs.c                   10    Termcap support for VMS/MS-DOS.
  133. X vms.c                     10    VMS Specific code.
  134. X vmsreadme.txt             11    Readme file for VMS.
  135. END_OF_FILE
  136. if test 2286 -ne `wc -c <'MANIFEST'`; then
  137.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  138. fi
  139. # end of 'MANIFEST'
  140. fi
  141. if test -f 'descrip.mms' -a "${1}" != "-c" ; then 
  142.   echo shar: Will not clobber existing file \"'descrip.mms'\"
  143. else
  144. echo shar: Extracting \"'descrip.mms'\" \(1579 characters\)
  145. sed "s/^X//" >'descrip.mms' <<'END_OF_FILE'
  146. XSOURCES =     BILL.C, CONFIG.C, CREATE.C, DATA.C, DIAG.C, DISPLAY.C, -
  147. X        FORTUNE.C, GLOBAL.C, HELP.C, IO.C, MAIN.C, MONSTER.C, -
  148. X        MOREOBJ.C, MOVEM.C, NAP.C, OBJECT.C, REGEN.C, SAVELEV.C, -
  149. X        SCORES.C, SIGNAL.C, STORE.C, TOK.C, VMS.C, -
  150. X        ACTION.C, FGETLR.C, TGETENT.C, TGETSTR.C, TGOTO.C, TPUTS.C
  151. X
  152. XOBJECTS =    BILL.OBJ, CONFIG.OBJ, CREATE.OBJ, DATA.OBJ, DIAG.OBJ, -
  153. X        DISPLAY.OBJ, FORTUNE.OBJ, GLOBAL.OBJ, HELP.OBJ, IO.OBJ, -
  154. X        MAIN.OBJ, MONSTER.OBJ, MOREOBJ.OBJ, MOVEM.OBJ, NAP.OBJ, -
  155. X        OBJECT.OBJ, REGEN.OBJ, SAVELEV.OBJ, SCORES.OBJ, SIGNAL.OBJ, -
  156. X        STORE.OBJ, TOK.OBJ, VMS.OBJ, -
  157. X        ACTION.OBJ, FGETLR.OBJ, TGETENT.OBJ, TGETSTR.OBJ, TGOTO.OBJ, -
  158. X        TPUTS.OBJ
  159. X
  160. XDOBJECTS =    BILL.DBJ, CONFIG.DBJ, CREATE.DBJ, DATA.DBJ, DIAG.DBJ, -
  161. X        DISPLAY.DBJ, FORTUNE.DBJ, GLOBAL.DBJ, HELP.DBJ, IO.DBJ, -
  162. X        MAIN.DBJ, MONSTER.DBJ, MOREOBJ.DBJ, MOVEM.DBJ, NAP.DBJ, -
  163. X        OBJECT.DBJ, REGEN.DBJ, SAVELEV.DBJ, SCORES.DBJ, SIGNAL.DBJ, -
  164. X        STORE.DBJ, TOK.DBJ, VMS.DBJ, -
  165. X        ACTION.DBJ, FGETLR.DBJ, TGETENT.DBJ, TGETSTR.DBJ, TGOTO.DBJ, -
  166. X        TPUTS.DBJ
  167. X
  168. XCDEFS =    /DEFINE=(LARNHOME="""larndir:""",DGK)
  169. X
  170. X.SUFFIXES
  171. X.SUFFIXES .OBJ .DBJ .C
  172. X
  173. XLARN.EXE : $(OBJECTS)
  174. X    LINK /NODEBUG/EXEC=LARN.EXE $(OBJECTS), sys$library:vaxcrtl.olb/libr
  175. X
  176. XLARND.EXE : $(DOBJECTS)
  177. X    LINK /DEBUG/EXEC=LARND.EXE $(DOBJECTS), sys$library:vaxcrtl.olb/libr
  178. X
  179. XLARNPCA.EXE : $(DOBJECTS), TERMCAP.OLB
  180. X        LINK /DEBUG=SYS$LIBRARY:PCA$OBJ.OBJ/EXEC=LARNPCA.EXE $(DOBJECTS),-
  181. X             SYS$LIBRARY:VAXCRTL.OLB/LIBR
  182. X
  183. X$(OBJECTS),$(DOBJECTS) : HEADER.H
  184. X
  185. X.C.OBJ
  186. X    CC $(CDEFS) /NODEB/OPTIM/OBJ=$*.OBJ $*.C
  187. X
  188. X.C.DBJ
  189. X    CC $(CDEFS) /DEBUG/NOOPT/OBJ=$*.DBJ $*.C
  190. END_OF_FILE
  191. if test 1579 -ne `wc -c <'descrip.mms'`; then
  192.     echo shar: \"'descrip.mms'\" unpacked with wrong size!
  193. fi
  194. # end of 'descrip.mms'
  195. fi
  196. if test -f 'main.c' -a "${1}" != "-c" ; then 
  197.   echo shar: Will not clobber existing file \"'main.c'\"
  198. else
  199. echo shar: Extracting \"'main.c'\" \(45396 characters\)
  200. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  201. X/*  main.c      */
  202. X
  203. X#ifdef MSDOS
  204. X#include "errno.h"
  205. X#include "setjmp.h"
  206. X#include "stdlib.h"
  207. X#endif
  208. X
  209. X#include "header.h"
  210. X#ifndef MSDOS
  211. X# ifndef VMS
  212. X#  include <pwd.h>
  213. X# endif VMS
  214. X#endif MSDOS
  215. X
  216. Xstatic char copyright[]="\nLarn is copyrighted 1986 by Noah Morgan.\n";
  217. Xint srcount=0;  /* line counter for showstr()   */
  218. Xint dropflag=0; /* if 1 then don't lookforobject() next round */
  219. Xint rmst=80;    /*  random monster creation counter     */
  220. Xint userid;     /* the players login user id number */
  221. Xchar nowelcome=0,nomove=0; /* if (nomove) then don't count next iteration as a
  222. X                              move */
  223. Xstatic char viewflag=0;    /* if viewflag then we have done a 99 stay here 
  224. X                              and don't showcell in the main loop */
  225. Xchar restorflag=0;         /* 1 means restore has been done    */
  226. Xchar prompt_mode = 0;         /* 1 if prompting for actions */
  227. X
  228. X#ifndef MSDOS
  229. X# ifndef VMS
  230. Xint ospeed = 0;
  231. Xchar PC = 0;
  232. X# endif VMS
  233. X#endif MSDOS
  234. X
  235. X#ifdef MSDOS
  236. X
  237. Xstatic char cmdhelp[] = "\
  238. XCmd line format: larn [-slicnhp] [-o<optsifle>] [-##] [++]\n\
  239. X  -s   show the scoreboard\n\
  240. X  -l   show the logfile (wizard id only)\n\
  241. X  -i   show scoreboard with inventories of dead characters\n\
  242. X  -c   create new scoreboard (wizard id only)\n\
  243. X  -n   suppress welcome message on starting game\n\
  244. X  -##  specify level of difficulty (example: -5)\n\
  245. X  -h   print this help text\n\
  246. X  -p   prompt for actions on objects\n\
  247. X  ++   restore game from checkpoint file\n\
  248. X  -o<optsfile>   specify larnopts filename to be used instead of \"larn.opt\"\n\
  249. X";
  250. X
  251. X# else
  252. X
  253. Xstatic char cmdhelp[] = "\
  254. XCmd line format: larn [-slicnhp] [-o<optsifle>] [-##] [++]\n\
  255. X  -s   show the scoreboard\n\
  256. X  -l   show the logfile (wizard id only)\n\
  257. X  -i   show scoreboard with inventories of dead characters\n\
  258. X  -c   create new scoreboard (wizard id only)\n\
  259. X  -n   suppress welcome message on starting game\n\
  260. X  -##  specify level of difficulty (example: -5)\n\
  261. X  -h   print this help text\n\
  262. X  -p   prompt for actions on objects\n\
  263. X  ++   restore game from checkpoint file\n\
  264. X  -o<optsfile>   specify .larnopts filename to be used instead of \"~/.larnopts\"\n\
  265. X";
  266. X
  267. X# endif
  268. X
  269. X#ifdef DGK_MSDOS
  270. Xint save_mode = 0;      /* 1 if doing a save game */
  271. Xjmp_buf save_jbuf;      /* To recover from disk full errors */
  272. X#endif
  273. X
  274. X#ifdef VT100
  275. Xstatic char *termtypes[] = { "vt100", "vt101", "vt102", "vt103", "vt125",
  276. X    "vt131", "vt140", "vt180", "vt220", "vt240", "vt241", "vt320", "vt340",
  277. X    "vt341"  };
  278. X#endif
  279. X/*
  280. X    ************
  281. X    MAIN PROGRAM
  282. X    ************
  283. X*/
  284. Xmain(argc,argv)
  285. X    int argc;
  286. X    char **argv;
  287. X    {
  288. X    register int i,j;
  289. X    int hard = -1;
  290. X    char *ptr=0,*ttype;
  291. X#ifndef MSDOS
  292. X    struct passwd *pwe,*getpwuid();
  293. X#endif
  294. X
  295. X/*
  296. X *  first task is to identify the player
  297. X */
  298. X#ifndef VT100
  299. X    init_term();    /* setup the terminal (find out what type) for termcap */
  300. X#endif
  301. X#ifdef MSDOS
  302. X    ptr = "PLAYER";
  303. X#else
  304. X#ifdef VMS
  305. X    ptr = getenv("USER");
  306. X#else
  307. X    if (((ptr = getlogin()) == 0) || (*ptr==0)) /* try to get login name */
  308. X      if (pwe=getpwuid(getuid())) /* can we get it from /etc/passwd? */
  309. X        ptr = pwe->pw_name;
  310. X      else
  311. X      if ((ptr = getenv("USER")) == 0)
  312. X        if ((ptr = getenv("LOGNAME")) == 0)
  313. X          {
  314. X          noone: write(2, "Can't find your logname.  Who Are You?\n",39);
  315. X                 exit();
  316. X          }
  317. X    if (ptr==0) goto noone;
  318. X    if (strlen(ptr)==0) goto noone;
  319. X#endif
  320. X#endif
  321. X
  322. X/*
  323. X *  second task is to prepare the pathnames the player will need
  324. X */
  325. X    strcpy(loginname,ptr); /* save loginname of the user for logging purposes */
  326. X    strcpy(logname,ptr);    /* this will be overwritten with the players name */
  327. X
  328. X/* Set up the input and output buffers.
  329. X */
  330. X    lpbuf    = (char *)malloc((5* BUFBIG)>>2);  /* output buffer */
  331. X    inbuffer = (char *)malloc((5*MAXIBUF)>>2);  /* output buffer */
  332. X    if ((lpbuf==0) || (inbuffer==0)) died(-285); /* malloc() failure */
  333. X
  334. X# ifdef DGK_MSDOS
  335. X    /* LARNHOME now comes from the options file, so it must be read in
  336. X     * before constructing the other file names.  Unfortunately we have
  337. X     * to look for the -o option now.
  338. X     */
  339. X    strcpy(optsfile, LARNOPTS);
  340. X    for (i = 1; i < argc; i++)
  341. X        if (strncmp(argv[i], "-o", 2) == 0) {
  342. X            argv[i][0] = 0;         /* remove this argv */
  343. X            if (argv[i][2] != '\0')
  344. X                strncpy(optsfile, &argv[i][2], PATHLEN);
  345. X            else {
  346. X                strncpy(optsfile, argv[i + 1], PATHLEN);
  347. X                argv[i + 1][0] = 0; /* and this argv */
  348. X            }
  349. X            optsfile[PATHLEN - 1] = 0;
  350. X            break;
  351. X        }
  352. X    readopts();
  353. X    append_slash(larndir);
  354. X
  355. X    /* Savefile and swapfile can be given explicitly as options
  356. X     */
  357. X    if (!savefilename[0]) {
  358. X        strcpy(savefilename, larndir);
  359. X        strcat(savefilename, SAVEFILE);
  360. X    }
  361. X    if (!swapfile[0]) {
  362. X        strcpy(swapfile, larndir);
  363. X        strcat(swapfile, SWAPFILE);
  364. X    }
  365. X    strcpy(scorefile, larndir);
  366. X    strcpy(logfile, larndir);
  367. X    strcpy(helpfile, larndir);
  368. X    strcpy(larnlevels, larndir);
  369. X    strcpy(fortfile, larndir);
  370. X    strcpy(playerids, larndir);
  371. X    strcpy(ckpfile, larndir);
  372. X
  373. X# else /* DGK_MSDOS */
  374. X
  375. X    if ((ptr = getenv("HOME")) == 0) ptr = ".";
  376. X#ifdef SAVEINHOME
  377. X    /* save file name in home directory */
  378. X# ifdef VMS
  379. X    sprintf(savefilename, "%s%s",ptr, SAVEFILE);
  380. X# else
  381. X    sprintf(savefilename, "%s/%s",ptr, SAVEFILE);
  382. X# endif VMS
  383. X#else
  384. X    strcat(savefilename,logname);   /* prepare savefile name */
  385. X    strcat(savefilename,".sav");    /* prepare savefile name */
  386. X#endif
  387. X#ifdef VMS
  388. X    sprintf(optsfile, "%s%s",ptr, LARNOPTS);   /* the options filename */
  389. X#else
  390. X    sprintf(optsfile, "%s/%s",ptr, LARNOPTS);   /* the options filename */
  391. X#endif VMS
  392. X
  393. X# endif /* DGK_MSDOS */
  394. X
  395. X    strcat(scorefile, SCORENAME);   /* the larn scoreboard filename */
  396. X    strcat(logfile, LOGFNAME);      /* larn activity logging filename */
  397. X    strcat(helpfile, HELPNAME);     /* the larn on-line help file */
  398. X    strcat(larnlevels, LEVELSNAME); /* the pre-made cave level data file */
  399. X    strcat(fortfile, FORTSNAME);    /* the fortune data file name */
  400. X    strcat(playerids, PLAYERIDS);   /* the playerid data file name */
  401. X    strcat(ckpfile, CKPFILE);
  402. X
  403. X# ifdef TIMECHECK
  404. X    strcat(holifile, HOLIFILE);     /* the holiday data file name */
  405. X# endif
  406. X
  407. X#ifdef VT100
  408. X/*
  409. X *  check terminal type to avoid users who have not vt100 type terminals
  410. X */
  411. X    ttype = getenv("TERM");
  412. X    for (j=1, i=0; i<sizeof(termtypes)/sizeof(char *); i++)
  413. X        if (strcmp(ttype,termtypes[i]) == 0) { j=0;  break; }
  414. X    if (j)
  415. X        {
  416. X        lprcat("Sorry, Larn needs a VT100 family terminal for all it's features.\n"); lflush();
  417. X        exit();
  418. X        }
  419. X#endif
  420. X
  421. X/*
  422. X *  now make scoreboard if it is not there (don't clear) 
  423. X */
  424. X    if (access(scorefile,0) == -1) /* not there */
  425. X        makeboard();
  426. X
  427. X/*
  428. X *  now process the command line arguments 
  429. X */
  430. X    for (i=1; i<argc; i++)
  431. X        {
  432. X        if (argv[i][0] == '-')
  433. X          switch(argv[i][1])
  434. X            {
  435. X        case 's':          /* show scoreboard   */
  436. X        showscores();
  437. X#ifdef VMS
  438. X        exit();
  439. X#else
  440. X        exit(0);
  441. X#endif
  442. X
  443. X            case 'l': /* show log file     */
  444. X            diedlog();
  445. X#ifdef VMS
  446. X        exit();
  447. X#else
  448. X        exit(0);
  449. X#endif
  450. X
  451. X        case 'i': showallscores();
  452. X        /* show all scoreboard */
  453. X#ifdef VMS
  454. X        exit();
  455. X#else
  456. X        exit(0);
  457. X#endif
  458. X
  459. X            case 'c':        /* anyone with password can create scoreboard */
  460. X                      lprcat("Preparing to initialize the scoreboard.\n");
  461. X                      if (getpassword() != 0)  /*make new scoreboard*/
  462. X                            {
  463. X                            makeboard(); lprc('\n'); showscores();
  464. X                            }
  465. X#ifdef VMS
  466. X        exit();
  467. X#else
  468. X        exit(0);
  469. X#endif
  470. X
  471. X            case 'n':   /* no welcome msg   */ nowelcome=1; argv[i][0]=0; break;
  472. X
  473. X            case '0': case '1': case '2': case '3': case '4': case '5':
  474. X            case '6': case '7': case '8': case '9': /* for hardness */
  475. X                hard = atoi(&argv[i][1]);
  476. X                break;
  477. X
  478. X            case 'h':   /* print out command line arguments */
  479. X            write(1,cmdhelp,sizeof(cmdhelp));
  480. X#ifdef VMS
  481. X        exit();
  482. X#else
  483. X        exit(0);
  484. X#endif
  485. X
  486. X            case 'o':   /* specify a .larnopts filename */
  487. X                        strncpy(optsfile,argv[i]+2,127);  break;
  488. X
  489. X            case 'p':   /* set 'prompt_mode' flag */
  490. X                prompt_mode = 1 ;
  491. X                break ;
  492. X
  493. X        default:    printf("Unknown option <%s>\n",argv[i]);
  494. X#ifdef VMS
  495. X        exit();
  496. X#else
  497. X        exit(0);
  498. X#endif
  499. X            };
  500. X
  501. X        if (strcmp(argv[i], "++") == 0)
  502. X            restorflag = 1;
  503. X    }
  504. X
  505. X#ifndef DGK_MSDOS
  506. X    readopts();     /* read the options file if there is one */
  507. X#endif
  508. X
  509. X#ifdef TIMECHECK
  510. X/*
  511. X *  this section of code checks to see if larn is allowed during working hours
  512. X */
  513. X    if (dayplay==0) /* check for not-during-daytime-hours */
  514. X      if (playable())
  515. X        {
  516. X        write(2,"Sorry, Larn can not be played during working hours.\n",52);
  517. X        exit();
  518. X        }
  519. X#endif TIMECHECK
  520. X
  521. X#ifdef UIDSCORE
  522. X    userid = geteuid(); /* obtain the user's effective id number */
  523. X#else UIDSCORE
  524. X    userid = getplid(logname);  /* obtain the players id number */
  525. X#endif UIDSCORE
  526. X#ifdef VMS
  527. X    wisid = userid;
  528. X#endif
  529. X    if (userid < 0) { write(2,"Can't obtain playerid\n",22);
  530. X#ifdef VMS
  531. X        exit();
  532. X#else
  533. X        exit(0);
  534. X#endif
  535. X    }
  536. X
  537. X#ifdef HIDEBYLINK
  538. X/*
  539. X *  this section of code causes the program to look like something else to ps
  540. X */
  541. X    if (strcmp(psname,argv[0])) /* if a different process name only */
  542. X        {
  543. X        if ((i=access(psname,1)) < 0)
  544. X            {       /* link not there */
  545. X            if (link(argv[0],psname)>=0)
  546. X                {
  547. X                argv[0] = psname;   execv(psname,argv);
  548. X                }
  549. X            }
  550. X        else
  551. X            unlink(psname);
  552. X        }
  553. X
  554. X    for (i=1; i<argc; i++)
  555. X        {
  556. X        szero(argv[i]); /* zero the argument to avoid ps snooping */
  557. X        }
  558. X#endif HIDEBYLINK
  559. X
  560. X/*
  561. X *  He really wants to play, so malloc the memory for the dungeon.
  562. X */
  563. X# ifdef MSDOS
  564. X    allocate_memory();
  565. X# else
  566. X    cell = (struct cel *)malloc(sizeof(struct cel)*(MAXLEVEL+MAXVLEVEL)*MAXX*MAXY);
  567. X    if (cell == 0) died(-285);  /* malloc failure */
  568. X# endif
  569. X    lcreat((char*)0);   newgame();      /*  set the initial clock  */
  570. X
  571. X    if (restorflag == 1) {          /* restore checkpoint file */
  572. X        clear();
  573. X        hitflag = 1;
  574. X        restoregame(ckpfile);
  575. X    } else if (access(savefilename,0)==0)   /* restore game if need to */
  576. X        {
  577. X        clear();    restorflag = 1;
  578. X        hitflag=1;  restoregame(savefilename);  /* restore last game    */
  579. X        }
  580. X    sigsetup();     /* trap all needed signals  */
  581. X    setupvt100();   /*  setup the terminal special mode             */
  582. X    sethard(hard);  /* set up the desired difficulty                */
  583. X    if (c[HP]==0)   /* create new game */
  584. X        {
  585. X        makeplayer();   /*  make the character that will play           */
  586. X        newcavelevel(0);/*  make the dungeon                            */
  587. X        predostuff = 1; /* tell signals that we are in the welcome screen */
  588. X        if (nowelcome==0) welcome();     /* welcome the player to the game */
  589. X# ifdef DGK_MSDOS
  590. X        /* Display their mail if they've just won the previous game
  591. X         */
  592. X        checkmail();
  593. X# endif
  594. X        }
  595. X
  596. X    lprc(T_INIT);   /* Reinit the screen because of welcome and check mail
  597. X             * having embedded escape sequences.*/
  598. X    drawscreen();   /*  show the initial dungeon                    */
  599. X    predostuff = 2; /* tell the trap functions that they must do a showplayer()
  600. X               from here on */
  601. X#if 0
  602. X    /* nice(1); /* games should be run niced */
  603. X#endif
  604. X    yrepcount = hit2flag = 0;
  605. X    while (1)
  606. X        {
  607. X        if (dropflag==0)
  608. X            /* see if there is an object here.
  609. X
  610. X           If in prompt mode, identify and prompt; else
  611. X           identify, pickup if ( auto pickup and not move-no-pickup ),
  612. X           never prompt.
  613. X        */
  614. X        if (prompt_mode)
  615. X        lookforobject( TRUE, FALSE, TRUE );
  616. X        else
  617. X        lookforobject( TRUE, ( auto_pickup ), FALSE );
  618. X        else
  619. X            dropflag=0; /* don't show it just dropped an item */
  620. X
  621. X    /* Move the monsters
  622. X    */
  623. X    if (hitflag==0)
  624. X        {
  625. X        if (c[HASTEMONST])
  626. X        movemonst();
  627. X        movemonst();
  628. X        }
  629. X
  630. X    /* show stuff around the player
  631. X    */
  632. X    if (viewflag==0)
  633. X        showcell(playerx,playery);
  634. X    else
  635. X        viewflag=0;
  636. X
  637. X    if (hit3flag) flushall();
  638. X        hitflag=hit3flag=0; nomove=1;
  639. X        bot_linex();    /* update bottom line */
  640. X        while (nomove)
  641. X            {
  642. X            if (hit3flag) flushall();
  643. X            nomove=0; parse();
  644. X            }   /*  get commands and make moves */
  645. X        regen();            /*  regenerate hp and spells            */
  646. X        if (c[TIMESTOP]==0)
  647. X            if (--rmst <= 0)
  648. X                { rmst = 120-(level<<2); fillmonst(makemonst(level)); }
  649. X        }
  650. X    }
  651. X
  652. X/*
  653. X    showstr()
  654. X
  655. X    show character's inventory
  656. X */
  657. Xshowstr()
  658. X    {
  659. X    register int i,number;
  660. X    for (number=3, i=0; i<26; i++)
  661. X        if (iven[i]) number++;  /* count items in inventory */
  662. X    t_setup(number);    qshowstr();   t_endup(number);
  663. X    }
  664. X
  665. Xqshowstr()
  666. X    {
  667. X    register int i,j,k,sigsav;
  668. X    srcount=0;  sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  669. X    if (c[GOLD]) { lprintf(".)   %d gold pieces",(long)c[GOLD]); srcount++; }
  670. X    for (k=25; k>=0; k--)   /* bug fix - dgk */
  671. X/*  for (k=26; k>=0; k--)            */
  672. X      if (iven[k])
  673. X        {  for (i=22; i<84; i++)
  674. X             for (j=0; j<=k; j++)  if (i==iven[j])  show3(j); k=0; }
  675. X
  676. X    lprintf("\nElapsed time is %d.  You have %d mobuls left",(long)((gtime+99)/100+1),(long)((TIMELIMIT-gtime)/100));
  677. X    more();     nosignal=sigsav;
  678. X    }
  679. X
  680. X/*
  681. X *  subroutine to clear screen depending on # lines to display
  682. X */
  683. Xt_setup(count)
  684. X    register int count;
  685. X    {
  686. X    if (count<20)  /* how do we clear the screen? */
  687. X        {
  688. X        cl_up(79,count);  cursor(1,1);
  689. X        }
  690. X    else
  691. X        {
  692. X        resetscroll(); clear();
  693. X        }
  694. X    }
  695. X
  696. X/*
  697. X *  subroutine to restore normal display screen depending on t_setup()
  698. X */
  699. Xt_endup(count)
  700. X    register int count;
  701. X    {
  702. X    if (count<18)  /* how did we clear the screen? */
  703. X        draws(0,MAXX,0,(count>MAXY) ? MAXY : count);
  704. X    else
  705. X        {
  706. X        drawscreen(); setscroll();
  707. X        }
  708. X    }
  709. X
  710. X/*
  711. X    function to show the things player is wearing only
  712. X */
  713. Xshowwear()
  714. X    {
  715. X    register int i,j,sigsav,count;
  716. X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  717. X    srcount=0;
  718. X
  719. X     for (count=2,j=0; j<=26; j++)   /* count number of items we will display */
  720. X       if (i=iven[j])
  721. X        switch(i)
  722. X            {
  723. X            case OLEATHER:  case OPLATE:    case OCHAIN:
  724. X            case ORING:     case OSTUDLEATHER:  case OSPLINT:
  725. X            case OPLATEARMOR:   case OSSPLATE:  case OSHIELD:
  726. X            count++;
  727. X            };
  728. X
  729. X    t_setup(count);
  730. X
  731. X    for (i=22; i<84; i++)
  732. X         for (j=0; j<=26; j++)
  733. X           if (i==iven[j])
  734. X            switch(i)
  735. X                {
  736. X                case OLEATHER:  case OPLATE:    case OCHAIN:
  737. X                case ORING:     case OSTUDLEATHER:  case OSPLINT:
  738. X                case OPLATEARMOR:   case OSSPLATE:  case OSHIELD:
  739. X                show3(j);
  740. X                };
  741. X    more();     nosignal=sigsav;    t_endup(count);
  742. X    }
  743. X
  744. X/*
  745. X    function to show the things player can wield only
  746. X */
  747. Xshowwield()
  748. X    {
  749. X    register int i,j,sigsav,count;
  750. X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  751. X    srcount=0;
  752. X
  753. X     for (count=2,j=0; j<=26; j++)  /* count how many items */
  754. X       if (i=iven[j])
  755. X        switch(i)
  756. X            {
  757. X            case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
  758. X            case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
  759. X            case OSPIRITSCARAB:  case OCUBEofUNDEAD:
  760. X            case OPOTION:   case OSCROLL:  break;
  761. X            default:  count++;
  762. X            };
  763. X
  764. X    t_setup(count);
  765. X
  766. X    for (i=22; i<84; i++)
  767. X         for (j=0; j<=26; j++)
  768. X           if (i==iven[j])
  769. X            switch(i)
  770. X                {
  771. X                case ODIAMOND:  case ORUBY:  case OEMERALD:  case OSAPPHIRE:
  772. X                case OBOOK:     case OCHEST:  case OLARNEYE: case ONOTHEFT:
  773. X                case OSPIRITSCARAB:  case OCUBEofUNDEAD:
  774. X                case OPOTION:   case OSCROLL:  break;
  775. X                default:  show3(j);
  776. X                };
  777. X    more();     nosignal=sigsav;    t_endup(count);
  778. X    }
  779. X
  780. X/*
  781. X *  function to show the things player can read only
  782. X */
  783. Xshowread()
  784. X    {
  785. X    register int i,j,sigsav,count;
  786. X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  787. X    srcount=0;
  788. X
  789. X    for (count=2,j=0; j<=26; j++)
  790. X        switch(iven[j])
  791. X            {
  792. X            case OBOOK: case OSCROLL:   count++;
  793. X            };
  794. X    t_setup(count);
  795. X
  796. X    for (i=22; i<84; i++)
  797. X         for (j=0; j<=26; j++)
  798. X           if (i==iven[j])
  799. X            switch(i)
  800. X                {
  801. X                case OBOOK: case OSCROLL:   show3(j);
  802. X                };
  803. X    more();     nosignal=sigsav;    t_endup(count);
  804. X    }
  805. X
  806. X/*
  807. X *  function to show the things player can eat only
  808. X */
  809. Xshoweat()
  810. X    {
  811. X    register int i,j,sigsav,count;
  812. X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  813. X    srcount=0;
  814. X
  815. X    for (count=2,j=0; j<=26; j++)
  816. X        switch(iven[j])
  817. X            {
  818. X            case OCOOKIE:   count++;
  819. X            };
  820. X    t_setup(count);
  821. X
  822. X    for (i=22; i<84; i++)
  823. X         for (j=0; j<=26; j++)
  824. X           if (i==iven[j])
  825. X            switch(i)
  826. X                {
  827. X                case OCOOKIE:   show3(j);
  828. X                };
  829. X    more();     nosignal=sigsav;    t_endup(count);
  830. X    }
  831. X
  832. X/*
  833. X    function to show the things player can quaff only
  834. X */
  835. Xshowquaff()
  836. X    {
  837. X    register int i,j,sigsav,count;
  838. X    sigsav=nosignal;  nosignal=1; /* don't allow ^c etc */
  839. X    srcount=0;
  840. X
  841. X    for (count=2,j=0; j<=26; j++)
  842. X        switch(iven[j])
  843. X            {
  844. X            case OPOTION:   count++;
  845. X            };
  846. X    t_setup(count);
  847. X
  848. X    for (i=22; i<84; i++)
  849. X         for (j=0; j<=26; j++)
  850. X           if (i==iven[j])
  851. X            switch(i)
  852. X                {
  853. X                case OPOTION:   show3(j);
  854. X                };
  855. X    more();     nosignal=sigsav;        t_endup(count);
  856. X    }
  857. X
  858. Xshow1(idx,str2)
  859. X    register int idx;
  860. X    register char *str2[];
  861. X    {
  862. X        lprc('\n');
  863. X        cltoeoln();
  864. X    if (str2==0)
  865. X        lprintf("%c)   %s",idx+'a',objectname[iven[idx]]);
  866. X    else if (*str2[ivenarg[idx]]==0)
  867. X        lprintf("%c)   %s",idx+'a',objectname[iven[idx]]);
  868. X    else
  869. X        lprintf("%c)   %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]);
  870. X    }
  871. X
  872. Xshow3(index)
  873. X    register int index;
  874. X    {
  875. X    switch(iven[index])
  876. X        {
  877. X        case OPOTION:   show1(index,potionname);  break;
  878. X        case OSCROLL:   show1(index,scrollname);  break;
  879. X
  880. X        case OLARNEYE:      case OBOOK:         case OSPIRITSCARAB:
  881. X        case ODIAMOND:      case ORUBY:         case OCUBEofUNDEAD:
  882. X        case OEMERALD:      case OCHEST:        case OCOOKIE:
  883. X        case OSAPPHIRE:     case ONOTHEFT:      show1(index,(char **)0);  break;
  884. X
  885. X        default:
  886. X        lprc('\n');
  887. X        cltoeoln();
  888. X        lprintf("%c)   %s",index+'a',objectname[iven[index]]);
  889. X        if (ivenarg[index]>0)
  890. X            lprintf(" + %d",(long)ivenarg[index]);
  891. X        else if (ivenarg[index]<0)
  892. X            lprintf(" %d",(long)ivenarg[index]);
  893. X        break;
  894. X        }
  895. X    if (c[WIELD]==index) lprcat(" (weapon in hand)");
  896. X    if ((c[WEAR]==index) || (c[SHIELD]==index))  lprcat(" (being worn)");
  897. X    if (++srcount>=22) { srcount=0; more(); clear(); }
  898. X    }
  899. X
  900. X/*
  901. X    subroutine to randomly create monsters if needed
  902. X */
  903. Xrandmonst()
  904. X    {
  905. X    if (c[TIMESTOP]) return;    /*  don't make monsters if time is stopped  */
  906. X    if (--rmst <= 0)
  907. X        {
  908. X        rmst = 120 - (level<<2);  fillmonst(makemonst(level));
  909. X        }
  910. X    }
  911. X
  912. X
  913. X/*
  914. X    parse()
  915. X
  916. X    get and execute a command
  917. X */
  918. Xparse()
  919. X    {
  920. X    register int i,j,k,flag;
  921. X
  922. X    while   (1)
  923. X        {
  924. X        k = yylex();
  925. X        switch(k)   /*  get the token from the input and switch on it   */
  926. X            {
  927. X            case 'h':   moveplayer(4);  return;     /*  west        */
  928. X            case 'H':   run(4);         return;     /*  west        */
  929. X            case 'l':   moveplayer(2);  return;     /*  east        */
  930. X            case 'L':   run(2);         return;     /*  east        */
  931. X            case 'j':   moveplayer(1);  return;     /*  south       */
  932. X            case 'J':   run(1);         return;     /*  south       */
  933. X            case 'k':   moveplayer(3);  return;     /*  north       */
  934. X            case 'K':   run(3);         return;     /*  north       */
  935. X            case 'u':   moveplayer(5);  return;     /*  northeast   */
  936. X            case 'U':   run(5);         return;     /*  northeast   */
  937. X            case 'y':   moveplayer(6);  return;     /*  northwest   */
  938. X            case 'Y':   run(6);         return;     /*  northwest   */
  939. X            case 'n':   moveplayer(7);  return;     /*  southeast   */
  940. X            case 'N':   run(7);         return;     /*  southeast   */
  941. X            case 'b':   moveplayer(8);  return;     /*  southwest   */
  942. X            case 'B':   run(8);         return;     /*  southwest   */
  943. X
  944. X            case '.':                               /*  stay here       */
  945. X                if (yrepcount) viewflag=1;
  946. X                return; 
  947. X
  948. X            case 'c':
  949. X                yrepcount=0;    
  950. X                cast();     
  951. X                return;     /*  cast a spell    */
  952. X
  953. X            case 'd':
  954. X                yrepcount=0;
  955. X                if (c[TIMESTOP]==0)
  956. X                    dropobj();
  957. X                return; /*  to drop an object   */
  958. X
  959. X            case 'e':
  960. X                yrepcount=0;
  961. X                if (c[TIMESTOP]==0) 
  962. X                    eatcookie(); 
  963. X                return; /*  to eat a fortune cookie */
  964. X
  965. X            case 'g':   
  966. X                yrepcount = 0 ;
  967. X                cursors();
  968. X                lprintf("\nThe stuff you are carrying presently weighs %d pounds",(long)packweight());
  969. X                break ;
  970. X
  971. X            case 'i':
  972. X                yrepcount=0;    
  973. X                nomove=1;  
  974. X                showstr();  
  975. X                return;     /*  status      */
  976. X
  977. X        case 'p':           /* pray at an altar */
  978. X        yrepcount = 0;
  979. X        if (!prompt_mode)
  980. X            pray_at_altar();
  981. X        else
  982. X            nomove = 1;
  983. X        return;
  984. X
  985. X            case 'q':           /* quaff a potion */
  986. X                yrepcount=0;
  987. X                if (c[TIMESTOP]==0)
  988. X                    quaff();
  989. X                return; 
  990. X
  991. X            case 'r':
  992. X                yrepcount=0;
  993. X                if (c[BLINDCOUNT])
  994. X                    { 
  995. X                    cursors(); 
  996. X                    lprcat("\nYou can't read anything when you're blind!");
  997. X                    }
  998. X                else if (c[TIMESTOP]==0)
  999. X                    readscr();
  1000. X                return;     /*  to read a scroll    */
  1001. X
  1002. X            case 's':
  1003. X                yrepcount = 0 ;
  1004. X                if (!prompt_mode)
  1005. X                    sit_on_throne();
  1006. X        else
  1007. X            nomove = 1;
  1008. X                return ;
  1009. X
  1010. X            case 't':                       /* Tidy up at fountain */
  1011. X                yrepcount = 0 ;
  1012. X                if (!prompt_mode)
  1013. X                    wash_fountain() ;
  1014. X        else
  1015. X            nomove = 1;
  1016. X                return ;
  1017. X
  1018. X            case 'v':   
  1019. X        yrepcount=0;    
  1020. X        cursors();
  1021. X                lprintf("\nCaverns of Larn, Version %d.%d, Diff=%d",(long)VERSION,(long)SUBVERSION,(long)c[HARDGAME]);
  1022. X                if (wizard) lprcat(" Wizard"); nomove=1;
  1023. X                if (cheat) lprcat(" Cheater");
  1024. X                lprcat(copyright);
  1025. X                return;
  1026. X
  1027. X            case 'w':                       /*  wield a weapon */
  1028. X                yrepcount=0;
  1029. X                wield();
  1030. X                return;
  1031. X
  1032. X        case 'A':
  1033. X        yrepcount = 0;
  1034. X        if (!prompt_mode)
  1035. X            desecrate_altar();
  1036. X        else
  1037. X            nomove = 1;
  1038. X        return;
  1039. X
  1040. X            case 'C':                       /* Close something */
  1041. X                yrepcount = 0 ;
  1042. X                if (!prompt_mode)
  1043. X                    close_something();
  1044. X        else
  1045. X            nomove = 1;
  1046. X                return;
  1047. X
  1048. X            case 'D':                       /* Drink at fountain */
  1049. X                yrepcount = 0 ;
  1050. X                if (!prompt_mode)
  1051. X                    drink_fountain() ;
  1052. X        else
  1053. X            nomove = 1;
  1054. X                return ;
  1055. X
  1056. X            case 'E':               /* Enter a building */
  1057. X                yrepcount = 0 ;
  1058. X                if (!prompt_mode)
  1059. X                    enter() ;
  1060. X        else
  1061. X            nomove = 1;
  1062. X                break ;
  1063. X
  1064. X            case 'G':               /* Give the stairs a kick */
  1065. X                yrepcount = 0 ;
  1066. X                if (!prompt_mode)
  1067. X                    kick_stairs();
  1068. X        else
  1069. X            nomove = 1;
  1070. X                return ;
  1071. X
  1072. X            case 'I':              /*  list spells and scrolls */
  1073. X                yrepcount=0;
  1074. X                seemagic(0);
  1075. X                nomove=1;
  1076. X                return;
  1077. X
  1078. X            case 'O':               /* Open something */
  1079. X                yrepcount = 0 ;
  1080. X                if (!prompt_mode)
  1081. X                    open_something();
  1082. X        else
  1083. X            nomove = 1;
  1084. X                return;
  1085. X
  1086. X            case 'P':   
  1087. X        cursors();
  1088. X                if (outstanding_taxes>0)
  1089. X                    lprintf("\nYou presently owe %d gp in taxes.",(long)outstanding_taxes);
  1090. X                else
  1091. X                    lprcat("\nYou do not owe any taxes.");
  1092. X                return;
  1093. X
  1094. X            case 'Q':    /*  quit        */
  1095. X        yrepcount=0;
  1096. X        quit(); 
  1097. X        nomove=1;   
  1098. X        return;
  1099. X
  1100. X            case 'R' :          /* remove gems from a throne */
  1101. X                yrepcount = 0 ;
  1102. X                if (!prompt_mode)
  1103. X                    remove_gems( );
  1104. X        else
  1105. X            nomove = 1;
  1106. X                return ;
  1107. X
  1108. X# ifdef DGK_MSDOS
  1109. X            case 'S':
  1110. X                /* Set up error recovery
  1111. X                 */
  1112. X                if (setjmp(save_jbuf) != 0) {
  1113. X
  1114. X                    /* can't use lwclose!
  1115. X                     */
  1116. X                    if (lfd > 2)
  1117. X                        close(lfd);
  1118. X                    lcreat(NULL);
  1119. X                    setscroll();
  1120. X                    cursors();
  1121. X                    lprcat("\nSave failed !\n");
  1122. X                    if (errno == ENOSPC)
  1123. X                        lprcat("Disk is full !\n");
  1124. X                    beep();
  1125. X                    (void) unlink(savefilename);
  1126. X                    save_mode = 0;
  1127. X                    yrepcount = 0;
  1128. X                    nomove = 1;
  1129. X                    break;
  1130. X                }
  1131. X
  1132. X                /* And do the save.
  1133. X                 */
  1134. X                cursors();
  1135. X                lprintf("\nSaving to `%s' . . . ", savefilename);
  1136. X                lflush();
  1137. X                save_mode = 1;
  1138. X                savegame(savefilename);
  1139. X                clear();
  1140. X                lflush();
  1141. X                wizard=1;
  1142. X                died(-257); /* doesn't return */
  1143. X                break;
  1144. X# else
  1145. X            case 'S':   clear();  lprcat("Saving . . ."); lflush();  
  1146. X                        savegame(savefilename); wizard=1; died(-257);   /*  save the game - doesn't return  */
  1147. X# endif DGK_MSDOS
  1148. X
  1149. X            case 'T':   yrepcount=0;    cursors();  if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
  1150. X                                        if (c[WEAR] != -1) { c[WEAR] = -1; lprcat("\nYour armor is off"); bottomline(); }
  1151. X                        else lprcat("\nYou aren't wearing anything");
  1152. X                        return;
  1153. X
  1154. X            case 'W':
  1155. X                yrepcount=0;
  1156. X                wear();
  1157. X                return; /*  wear armor  */
  1158. X
  1159. X            case 'Z':   
  1160. X                yrepcount=0;
  1161. X                if (c[LEVEL]>9) 
  1162. X                    { 
  1163. X                    oteleport(1);
  1164. X                    return; 
  1165. X                    }
  1166. X                cursors(); 
  1167. X                lprcat("\nAs yet, you don't have enough experience to use teleportation");
  1168. X                return; /*  teleport yourself   */
  1169. X
  1170. X            case ' ':   yrepcount=0;    nomove=1;  return;
  1171. X
  1172. X# ifdef DGK_MSDOS
  1173. X            case 'V':
  1174. X                yrepcount = 0;
  1175. X                nomove = 1;
  1176. X                cursors();
  1177. X                lprcat("\nMSDOS version 12a by Don Kneller, Berkeley CA.\n");
  1178. X                lprcat("Version 12.1 by Kevin Routley\n");
  1179. X                return;
  1180. X
  1181. X            case 'D'-64:
  1182. X                yrepcount = 0;
  1183. X                nomove = 1;
  1184. X                levelinfo();
  1185. X                return;
  1186. X# endif
  1187. X
  1188. X            case 'L'-64:  yrepcount=0;  drawscreen();  nomove=1; return;    /*  look        */
  1189. X
  1190. X#if WIZID
  1191. X#ifdef EXTRA
  1192. X            case 'A'-64:    yrepcount=0;    nomove=1; if (wizard) { diag(); return; }  /*   create diagnostic file */
  1193. X                        return;
  1194. X#endif
  1195. X#endif
  1196. X            case '<':                       /* Go up stairs or vol shaft */
  1197. X                yrepcount = 0 ;
  1198. X                if (!prompt_mode)
  1199. X                    up_stairs();
  1200. X        else
  1201. X            nomove = 1;
  1202. X                return ;
  1203. X
  1204. X            case '>':                       /* Go down stairs or vol shaft*/
  1205. X                yrepcount = 0 ;
  1206. X                if (!prompt_mode)
  1207. X                    down_stairs();
  1208. X        else
  1209. X            nomove = 1;
  1210. X                return ;
  1211. X
  1212. X            case '?':                       /* give the help screen */
  1213. X                yrepcount=0;    
  1214. X                help(); 
  1215. X                nomove=1;
  1216. X                return; 
  1217. X
  1218. X        case ',':                       /* pick up an item */
  1219. X            yrepcount = 0 ;
  1220. X            if (!prompt_mode)
  1221. X            /* pickup, don't identify or prompt for action */
  1222. X            lookforobject( FALSE, TRUE, FALSE );
  1223. X        else
  1224. X            nomove = 1;
  1225. X        return;
  1226. X
  1227. X            case ':':                       /* look at object */
  1228. X                yrepcount = 0 ;
  1229. X                if (!prompt_mode)
  1230. X            /* identify, don't pick up or prompt for action */
  1231. X                    lookforobject( TRUE, FALSE, FALSE );
  1232. X                nomove = 1;  /* assumes look takes no time */
  1233. X                return;
  1234. X
  1235. X        case '@':        /* toggle auto-pickup */
  1236. X        yrepcount = 0 ;
  1237. X        nomove = 1;
  1238. X        cursors();
  1239. X        lprcat("\nAuto pickup: ");
  1240. X        auto_pickup = !auto_pickup;
  1241. X        if (auto_pickup)
  1242. X            lprcat("On.");
  1243. X        else
  1244. X            lprcat("Off.");
  1245. X        return;
  1246. X
  1247. X        case '^':                       /* identify traps */
  1248. X                flag = yrepcount = 0;
  1249. X                cursors();
  1250. X                lprc('\n');
  1251. X                for (j=playery-1; j<playery+2; j++)
  1252. X                    {
  1253. X                    if (j < 0) 
  1254. X                        j=0;        
  1255. X                    if (j >= MAXY)
  1256. X                        break;
  1257. X                    for (i=playerx-1; i<playerx+2; i++)
  1258. X                        {
  1259. X                        if (i < 0) 
  1260. X                            i=0;
  1261. X                        if (i >= MAXX) 
  1262. X                            break;
  1263. X                        switch(item[i][j])
  1264. X                            {
  1265. X                            case OTRAPDOOR:     case ODARTRAP:
  1266. X                            case OTRAPARROW:    case OTELEPORTER:
  1267. X                            case OPIT:
  1268. X                                lprcat("\nIts ");
  1269. X                                lprcat(objectname[item[i][j]]);  
  1270. X                                flag++;
  1271. X                            };
  1272. X                        }
  1273. X                    }
  1274. X                if (flag==0) 
  1275. X                    lprcat("\nNo traps are visible");
  1276. X                return;
  1277. X
  1278. X#if WIZID
  1279. X            case '_':   /*  this is the fudge player password for wizard mode*/
  1280. X                        yrepcount=0;    cursors(); nomove=1;
  1281. X# ifndef MSDOS
  1282. X                        if (userid!=wisid)
  1283. X                            {
  1284. X                            lprcat("Sorry, you are not empowered to be a wizard.\n");
  1285. X                            scbr(); /* system("stty -echo cbreak"); */
  1286. X                            lflush();  return;
  1287. X                            }
  1288. X# endif
  1289. X                        if (getpassword()==0)
  1290. X                            {
  1291. X                            scbr(); /* system("stty -echo cbreak"); */ return;
  1292. X                            }
  1293. X                        wizard=1;  scbr(); /* system("stty -echo cbreak"); */
  1294. X                        for (i=0; i<6; i++)  c[i]=70;  iven[0]=iven[1]=0;
  1295. X                        take(OPROTRING,50);   take(OLANCE,25);  c[WIELD]=1;
  1296. X                        c[LANCEDEATH]=1;   c[WEAR] = c[SHIELD] = -1;
  1297. X                        raiseexperience(6000000L);  c[AWARENESS] += 25000;
  1298. X                        {
  1299. X                        register int i,j;
  1300. X                        for (i=0; i<MAXY; i++)
  1301. X                            for (j=0; j<MAXX; j++)  know[j][i]=KNOWALL;
  1302. X                        for (i=0; i<SPNUM; i++) spelknow[i]=1;
  1303. X                        for (i=0; i<MAXSCROLL; i++)  scrollname[i][0]=' ';
  1304. X                        for (i=0; i<MAXPOTION; i++)  potionname[i][0]=' ';
  1305. X                        }
  1306. X                        for (i=0; i<MAXSCROLL; i++)
  1307. X                          if (strlen(scrollname[i])>2) /* no null items */
  1308. X                            { item[i][0]=OSCROLL; iarg[i][0]=i; }
  1309. X                        for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
  1310. X                          if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
  1311. X                            { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
  1312. X                        for (i=1; i<MAXY; i++)
  1313. X                            { item[0][i]=i; iarg[0][i]=0; }
  1314. X                        for (i=MAXY; i<MAXY+MAXX; i++)
  1315. X                            { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
  1316. X            for (i=MAXX+MAXY; i<MAXOBJECT; i++)
  1317. X                {
  1318. X                item[MAXX-1][i-MAXX-MAXY]=i;
  1319. X                iarg[MAXX-1][i-MAXX-MAXY]=0;
  1320. X                }
  1321. X                        c[GOLD]+=250000;    drawscreen();   return;
  1322. X#endif
  1323. X
  1324. X            };
  1325. X        }
  1326. X    }
  1327. X
  1328. Xparse2()
  1329. X    {
  1330. X    if (c[HASTEMONST]) movemonst(); movemonst(); /* move the monsters       */
  1331. X    randmonst();    regen();
  1332. X    }
  1333. X
  1334. Xrun(dir)
  1335. X    int dir;
  1336. X    {
  1337. X    register int i;
  1338. X    i=1; while (i)
  1339. X        {
  1340. X        i=moveplayer(dir);
  1341. X        if (i>0) {  if (c[HASTEMONST]) movemonst();  movemonst(); randmonst(); regen(); }
  1342. X        if (hitflag) i=0;
  1343. X        if (i!=0)  showcell(playerx,playery);
  1344. X        }
  1345. X    }
  1346. X
  1347. X/*
  1348. X    function to wield a weapon
  1349. X */
  1350. Xwield()
  1351. X    {
  1352. X    register int i;
  1353. X    while (1)
  1354. X        {
  1355. X    if ((i = whatitem("wield (- for nothing)"))=='\33')  return;
  1356. X        if (i != '.')
  1357. X            {
  1358. X            if (i=='*') showwield();
  1359. X        else if ( i == '-' ) { c[WIELD] = -1 ; return; }
  1360. X        else if (iven[i-'a']==0) { ydhi(i); return; }
  1361. X            else if (iven[i-'a']==OPOTION) { ycwi(i); return; }
  1362. X            else if (iven[i-'a']==OSCROLL) { ycwi(i); return; }
  1363. X            else  if ((c[SHIELD]!= -1) && (iven[i-'a']==O2SWORD)) { lprcat("\nBut one arm is busy with your shield!"); return; }
  1364. X            else  { c[WIELD]=i-'a'; if (iven[i-'a'] == OLANCE) c[LANCEDEATH]=1; else c[LANCEDEATH]=0;  bottomline(); return; }
  1365. X            }
  1366. X        }
  1367. X    }
  1368. X
  1369. X/*
  1370. X    common routine to say you don't have an item
  1371. X */
  1372. Xydhi(x)
  1373. X    int x;
  1374. X    { cursors();  lprintf("\nYou don't have item %c!",x); }
  1375. Xycwi(x)
  1376. X    int x;
  1377. X    { cursors();  lprintf("\nYou can't wield item %c!",x); }
  1378. X
  1379. X/*
  1380. X    function to wear armor
  1381. X */
  1382. Xwear()
  1383. X    {
  1384. X    register int i;
  1385. X    while (1)
  1386. X        {
  1387. X        if ((i = whatitem("wear"))=='\33')  return;
  1388. X    if (i != '.' && i != '-')
  1389. X            {
  1390. X            if (i=='*') showwear(); else
  1391. X            switch(iven[i-'a'])
  1392. X                {
  1393. X                case 0:  ydhi(i); return;
  1394. X                case OLEATHER:  case OCHAIN:  case OPLATE:  case OSTUDLEATHER:
  1395. X                case ORING:     case OSPLINT:   case OPLATEARMOR:   case OSSPLATE:
  1396. X                        if (c[WEAR] != -1) { lprcat("\nYou're already wearing some armor"); return; }
  1397. X                            c[WEAR]=i-'a';  bottomline(); return;
  1398. X                case OSHIELD:   if (c[SHIELD] != -1) { lprcat("\nYou are already wearing a shield"); return; }
  1399. X                                if (iven[c[WIELD]]==O2SWORD) { lprcat("\nYour hands are busy with the two handed sword!"); return; }
  1400. X                                c[SHIELD] = i-'a';  bottomline(); return;
  1401. X                default:    lprcat("\nYou can't wear that!");
  1402. X                };
  1403. X            }
  1404. X        }
  1405. X    }
  1406. X
  1407. X/*
  1408. X    function to drop an object
  1409. X */
  1410. Xdropobj()
  1411. X    {
  1412. X    register int i;
  1413. X    register char *p;
  1414. X    long amt;
  1415. X    p = &item[playerx][playery];
  1416. X    while (1)
  1417. X        {
  1418. X        if ((i = whatitem("drop"))=='\33')  return;
  1419. X    if (i=='*') showstr();
  1420. X    else if ( i != '-' )
  1421. X            {
  1422. X            if (i=='.') /* drop some gold */
  1423. X                {
  1424. X                if (*p) { lprcat("\nThere's something here already!"); return; }
  1425. X                lprcat("\n\n");
  1426. X                cl_dn(1,23);
  1427. X                lprcat("How much gold do you drop? ");
  1428. X                if ((amt=readnum((long)c[GOLD])) == 0) return;
  1429. X                if (amt>c[GOLD])
  1430. X                    {
  1431. X#ifdef VMS
  1432. X            lprcat("You don't have that much!");
  1433. X#else
  1434. X            lprcat("\nYou don't have that much!");
  1435. X#endif VMS
  1436. X            return; }
  1437. X                if (amt<=32767)
  1438. X                    { *p=OGOLDPILE; i=amt; }
  1439. X                else if (amt<=327670L)
  1440. X                    { *p=ODGOLD; i=amt/10; amt = 10L*i; }
  1441. X                else if (amt<=3276700L)
  1442. X                    { *p=OMAXGOLD; i=amt/100; amt = 100L*i; }
  1443. X                else if (amt<=32767000L)
  1444. X                    { *p=OKGOLD; i=amt/1000; amt = 1000L*i; }
  1445. X                else
  1446. X                    { *p=OKGOLD; i=32767; amt = 32767000L; }
  1447. X                c[GOLD] -= amt;
  1448. X#ifdef VMS
  1449. X                lprintf("You drop %d gold pieces",(long)amt);
  1450. X#else
  1451. X                lprintf("\nYou drop %d gold pieces",(long)amt);
  1452. X#endif VMS
  1453. X                iarg[playerx][playery]=i; bottomgold();
  1454. X                know[playerx][playery]=0; dropflag=1;  return;
  1455. X                }
  1456. X            drop_object(i-'a');
  1457. X            return;
  1458. X            }
  1459. X        }
  1460. X    }
  1461. X
  1462. X/*
  1463. X    readscr(), eatcookie(), quaff() could all be common code
  1464. X*/
  1465. X/*
  1466. X *  readscr()       Subroutine to read a scroll one is carrying
  1467. X */
  1468. Xreadscr()
  1469. X    {
  1470. X    register int i;
  1471. X    char tempc;
  1472. X
  1473. X    /* check for player standing on a book/scroll.  If he is, prompt for
  1474. X       and let him read it.  If player ESCs from prompt, quit the Read
  1475. X       command.
  1476. X    */
  1477. X    cursors();
  1478. X    i = item[playerx][playery];
  1479. X    if ((i == OSCROLL) ||
  1480. X        (i == OBOOK))
  1481. X        {
  1482. X        lprintf("\nThere is %s", objectname[i]); 
  1483. X        if (i==OSCROLL)
  1484. X            if (scrollname[iarg[playerx][playery]][0] != 0 )
  1485. X                lprintf(" of%s", scrollname[iarg[playerx][playery]] );
  1486. X        lprcat(" here.  Read it?");
  1487. X        if ((tempc = getyn()) == 'y')
  1488. X            {
  1489. X        if (i==OBOOK)
  1490. X                readbook( iarg[playerx][playery] );
  1491. X        else
  1492. X        read_scroll( iarg[playerx][playery] );
  1493. X        forget();
  1494. X            return;
  1495. X            }
  1496. X        else if (tempc != 'n' )
  1497. X            return;
  1498. X        }
  1499. X
  1500. X    while (1)
  1501. X        {
  1502. X        if ((i = whatitem("read"))=='\33')  return;
  1503. X    if (i != '.' && i != '-')
  1504. X            {
  1505. X            if (i=='*') showread(); else
  1506. X                {
  1507. X                if (iven[i-'a']==OSCROLL) { read_scroll(ivenarg[i-'a']); iven[i-'a']=0; return; }
  1508. X                if (iven[i-'a']==OBOOK)   { readbook(ivenarg[i-'a']);  iven[i-'a']=0; return; }
  1509. X                if (iven[i-'a']==0) { ydhi(i); return; }
  1510. X                lprcat("\nThere's nothing on it to read");  return;
  1511. X                }
  1512. X            }
  1513. X        }
  1514. X    }
  1515. X
  1516. X/*
  1517. X *  subroutine to eat a cookie one is carrying
  1518. X */
  1519. Xeatcookie()
  1520. X{
  1521. Xregister int i;
  1522. Xchar *p;
  1523. Xwhile (1)
  1524. X    {
  1525. X    char tempc;
  1526. X
  1527. X    /* check for player standing on a cookie.  If he is, prompt for 
  1528. X       and let him eat it.  If player ESCs from prompt, quit the Eat
  1529. X       command.
  1530. X    */
  1531. X    cursors();
  1532. X    i = item[playerx][playery];
  1533. X    if (i == OCOOKIE)
  1534. X        {
  1535. X        lprcat("\nThere is a fortune cookie here.  Eat it?");
  1536. X        if ((tempc = getyn()) == 'y')
  1537. X            {
  1538. X/* THIS COULD BE COMMON CODE !!! */
  1539. X            lprcat("\nThe cookie was delicious.");
  1540. X        forget();
  1541. X            if (!c[BLINDCOUNT])
  1542. X                {
  1543. X# ifdef MSDOS
  1544. X                outfortune();
  1545. X# else
  1546. X                if (p=fortune(fortfile))
  1547. X                    {
  1548. X                    lprcat("  Inside you find a scrap of paper that says:\n");
  1549. X                    lprcat(p);
  1550. X                    }
  1551. X# endif
  1552. X        }
  1553. X            return;
  1554. X            }
  1555. X        else if (tempc != 'n' )
  1556. X            return;
  1557. X        }
  1558. X
  1559. X    if ((i = whatitem("eat"))=='\33')  return;
  1560. X    if (i != '.' && i != '-' )
  1561. X        if (i=='*') showeat(); else
  1562. X            {
  1563. X            if (iven[i-'a']==OCOOKIE)
  1564. X                {
  1565. X                lprcat("\nThe cookie was delicious.");
  1566. X                iven[i-'a']=0;
  1567. X                if (!c[BLINDCOUNT])
  1568. X                    {
  1569. X# ifdef MSDOS
  1570. X                    outfortune();
  1571. X# else
  1572. X                    if (p=fortune(fortfile))
  1573. X                        {
  1574. X                        lprcat("  Inside you find a scrap of paper that says:\n");
  1575. X                        lprcat(p);
  1576. X                        }
  1577. X# endif
  1578. X                    }
  1579. X                return;
  1580. X                }
  1581. X            if (iven[i-'a']==0) { ydhi(i); return; }
  1582. X            lprcat("\nYou can't eat that!");  return;
  1583. X            }
  1584. X    }
  1585. X}
  1586. X
  1587. X/*
  1588. X *  subroutine to quaff a potion one is carrying
  1589. X */
  1590. Xquaff()
  1591. X    {
  1592. X    register int i;
  1593. X    char tempc;
  1594. X
  1595. X    /* check for player standing on a potion.  If he is, prompt for
  1596. X       and let him quaff it.  If player ESCs from prompt, quit the Quaff
  1597. X       command.
  1598. X    */
  1599. X    cursors();
  1600. X    i = item[playerx][playery];
  1601. X    if (i == OPOTION)
  1602. X        {
  1603. X        lprintf("\nThere is %s", objectname[i]); 
  1604. X        if (potionname[iarg[playerx][playery]][0] != 0 )
  1605. X            lprintf(" of%s", potionname[iarg[playerx][playery]] );
  1606. X        lprcat(" here.  Quaff it?");
  1607. X        if ((tempc = getyn()) == 'y')
  1608. X            {
  1609. X        quaffpotion( iarg[playerx][playery] );
  1610. X        forget();
  1611. X            return;
  1612. X            }
  1613. X        else if (tempc != 'n' )
  1614. X            return;
  1615. X        }
  1616. X
  1617. X    while (1)
  1618. X        {
  1619. X        if ((i = whatitem("quaff"))=='\33')
  1620. X            return;
  1621. X    if (i != '.' && i != '-' )
  1622. X            {
  1623. X            if (i=='*')
  1624. X                showquaff();
  1625. X            else
  1626. X                {
  1627. X                if (iven[i-'a']==OPOTION)
  1628. X                    {
  1629. X                    quaffpotion(ivenarg[i-'a'], TRUE);
  1630. X                    iven[i-'a']=0;
  1631. X                    return;
  1632. X                    }
  1633. X                if (iven[i-'a']==0) 
  1634. X                    { 
  1635. X                    ydhi(i); 
  1636. X                    return;
  1637. X                    }
  1638. X                lprcat("\nYou wouldn't want to quaff that, would you? ");
  1639. X                return;
  1640. X                }
  1641. X            }
  1642. X        }
  1643. X    }
  1644. X
  1645. X/*
  1646. X    function to ask what player wants to do
  1647. X */
  1648. Xstatic whatitem(str)
  1649. X    char *str;
  1650. X    {
  1651. X    int i;
  1652. X    cursors();  lprintf("\nWhat do you want to %s [* for all] ? ",str);
  1653. X    i=0; while (i>'z' || (i<'a' && i!='-' && i!='*' && i!='\33' && i!='.'))
  1654. X    i=ttgetch();
  1655. X    if (i=='\33')  lprcat(" aborted");
  1656. X    return(i);
  1657. X    }
  1658. X
  1659. X/*
  1660. X    subroutine to get a number from the player
  1661. X    and allow * to mean return amt, else return the number entered
  1662. X */
  1663. Xunsigned long readnum(mx)
  1664. X    long mx;
  1665. X    {
  1666. X    register int i;
  1667. X    register unsigned long amt=0;
  1668. X
  1669. X    sncbr();
  1670. X    /* allow him to say * for all gold 
  1671. X    */
  1672. X    if ((i=ttgetch()) == '*')
  1673. X        amt = mx;
  1674. X    else
  1675. X        /* read chars into buffer, deleting when requested */
  1676. X    while (i != '\n')
  1677. X            {
  1678. X        if (i=='\033') { scbr(); lprcat(" aborted"); return(0); }
  1679. X        if ((i <= '9') && (i >= '0') && (amt<999999999))
  1680. X            amt = amt*10+i-'0';
  1681. X        if ((i=='\010') || (i=='\177'))
  1682. X            amt = (long)(amt / 10) ;
  1683. X        i = ttgetch();
  1684. X        }
  1685. X    scbr();  
  1686. X    return(amt);
  1687. X    }
  1688. X
  1689. X#ifdef HIDEBYLINK
  1690. X/*
  1691. X *  routine to zero every byte in a string
  1692. X */
  1693. Xszero(str)
  1694. X    register char *str;
  1695. X    {
  1696. X    while (*str)
  1697. X        *str++ = 0;
  1698. X    }
  1699. X#endif HIDEBYLINK
  1700. X
  1701. X#ifdef TIMECHECK
  1702. X/*
  1703. X *  routine to check the time of day and return 1 if its during work hours
  1704. X *  checks the file ".holidays" for forms like "mmm dd comment..."
  1705. X */
  1706. Xint playable()
  1707. X    {
  1708. X    long g_time,time();
  1709. X    int hour,day,year;
  1710. X    char *date,*month,*p;
  1711. X
  1712. X    time(&g_time);  /* get the time and date */
  1713. X    date = ctime(&g_time); /* format: Fri Jul  4 00:27:56 EDT 1986 */
  1714. X    year = atoi(date+20);
  1715. X    hour = (date[11]-'0')*10 + date[12]-'0';
  1716. X    day  = (date[8]!=' ') ? ((date[8]-'0')*10 + date[9]-'0') : (date[9]-'0');
  1717. X    month = date+4;  date[7]=0; /* point to and NULL terminate month */
  1718. X
  1719. X    if (((hour>=8 && hour<17)) /* 8AM - 5PM */
  1720. X        && strncmp("Sat",date,3)!=0     /* not a Saturday */
  1721. X        && strncmp("Sun",date,3)!=0)    /* not a Sunday */
  1722. X            {
  1723. X        /* now check for a .holidays datafile */
  1724. X            lflush();
  1725. X            if (lopen(holifile) >= 0)
  1726. X                for ( ; ; )
  1727. X                    {
  1728. X                    if ((p=lgetw())==0) break;
  1729. X                    if (strlen(p)<6) continue;
  1730. X                    if ((strncmp(p,month,3)==0) && (day==atoi(p+4)) && (year==atoi(p+7)))
  1731. X                        return(0); /* a holiday */
  1732. X                    }
  1733. X            lrclose();  lcreat((char*)0);
  1734. X            return(1);
  1735. X            }
  1736. X    return(0);
  1737. X    }
  1738. X#endif TIMECHECK
  1739. END_OF_FILE
  1740. if test 45396 -ne `wc -c <'main.c'`; then
  1741.     echo shar: \"'main.c'\" unpacked with wrong size!
  1742. fi
  1743. # end of 'main.c'
  1744. fi
  1745. echo shar: End of archive 1 \(of 11\).
  1746. cp /dev/null ark1isdone
  1747. MISSING=""
  1748. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1749.     if test ! -f ark${I}isdone ; then
  1750.     MISSING="${MISSING} ${I}"
  1751.     fi
  1752. done
  1753. if test "${MISSING}" = "" ; then
  1754.     echo You have unpacked all 11 archives.
  1755.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1756. else
  1757.     echo You still need to unpack the following archives:
  1758.     echo "        " ${MISSING}
  1759. fi
  1760. ##  End of shell archive.
  1761. exit 0
  1762.